package org.jeecg.modules.simulator.rooter;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.Getter;
import lombok.Setter;
import org.jeecg.modules.common.CommonMQTTConstant;
import org.jeecg.modules.mqtt.MQTTSend;
import org.jeecg.modules.mqtt.MQTTUtils;
import org.jeecg.modules.simulator.jsonot.AfterFiveMinPeople;
import org.jeecg.modules.simulator.jsonot.BeforeFiveMinPeople;
import org.jeecg.modules.simulator.model.SceneParam;
import org.jeecg.modules.simulator.model.line.station.station.Station;
import org.jeecg.modules.simulator.model.line.station.station.TransferStation;
import org.jeecg.modules.simulator.util.TimeUtil;
import org.jeecg.modules.simulator.util.UnitCache;
import org.jeecg.modules.simulator.vo.*;
import org.jeecg.modules.simulator.recorder.ParkCurInfoVo;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @program: simulator-b20240918
 * @description:
 * 1、5分钟前的进站数据
 * 2、断面信息
 * 3、线路信息
 * 4、车辆信息
 * 5、进度信息
 * 6、时间
 * @author: renzhg
 * @create: 2024-11-01 10:59
 **/
public class RootPublisher {

    @Getter
    @Setter
    private Map<String, LineRooter> lineRooterMap;

    @Setter
    String earliestRecordTime;//最早记录的5分钟前时间点
    //key是时间
    Map<String, List<BeforeFiveMinPeople>> beforeFiveMinPeopleMapEverypt;

    //key是时间
    Map<String, List<AfterFiveMinPeople>> afterFiveMinPeopleMapEverypt;
    @Setter
    String sceneCode;
    MQTTSend mqttSend = new MQTTSend();


    //key是时间
    @Getter
    Map<String, List<LineCurInfoVo>> lineCurInfoVoListMap = new HashMap<>();
    @Getter
    Map<String, List<TrainCurInfoVo>> trainCurInfoVoListMap = new HashMap<>();


    public RootPublisher() {
        beforeFiveMinPeopleMapEverypt = new HashMap<>();
        afterFiveMinPeopleMapEverypt = new HashMap<>();

    }


    public Map<String,List<BeforeFiveMinPeople>>  getBeforeFiveMinPeople(String now) {
        recordPeople(now);
        return beforeFiveMinPeopleMapEverypt;
    }

    /**
     * @description: 5分钟前的进站数据
     * @author: renzhg
     * @date: 2025/2/7 14:53
     **/
    public void sendPassFiveMinPeople(String now, LocalTime startTime,List<BeforeFiveMinPeople> bfmplist) {

        LocalTime localTime = LocalTime.parse(now);
        mqttSend.passFiveSimStationInfo(startTime, localTime, bfmplist);
    }



    public  List<SectCurInfoVo> getSectInfo(String now){
        List<SectCurInfoVo> sectCurInfoVoList = new ArrayList<>();

        Map<String, List<TrainCurInfoVo>> trainCurInfoVoListMap = getTrainCurInfoVoListMap();
        List<TrainCurInfoVo> trainCurInfoVoList = trainCurInfoVoListMap.get(now);
        for (TrainCurInfoVo trainCurInfoVo : trainCurInfoVoList) {
            Map<String, TrainPosition> trainPositionMap = trainCurInfoVo.getAllCurTrainPosition();
            Map<String, TrainDyInfo> allCurTrainDyInfoMap = trainCurInfoVo.getAllCurTrainDyInfo();
            for (Map.Entry<String, TrainPosition> trainPositionEntry : trainPositionMap.entrySet()) {
                if (allCurTrainDyInfoMap.containsKey(trainPositionEntry.getKey())) {
                    SectCurInfoVo sectCurInfoVo = new SectCurInfoVo();
                    TrainDyInfo trainDyInfo = allCurTrainDyInfoMap.get(trainPositionEntry.getKey());
                    TrainPosition trainPosition = trainPositionEntry.getValue();
                    sectCurInfoVo.setSectName(trainPosition.getOrbitName());
                    sectCurInfoVo.setSectId(trainPosition.getOrbitId());
                    sectCurInfoVo.setPersonNum(trainDyInfo.getCurPersonNumbers());
                    sectCurInfoVo.setTrainNum(1);
                    sectCurInfoVoList.add(sectCurInfoVo);
                }
            }
        }

        return sectCurInfoVoList;
    }
    /**
     * @description: 发送断面信息---断面ID，断面名称，断面人数，断面车辆数
     * @author: renzhg
     * @date: 2025/2/7 14:54
     **/
    public void sendSectInfo(String now, LocalTime startTime, List<SectCurInfoVo> sectCurInfoVoList) {
        LocalTime localTime = LocalTime.parse(now);

        mqttSend.sendSectCurrentTime(startTime, localTime, sectCurInfoVoList);

    }



    public  List<LineCurInfoVo>   getLineCurInfoVoList(String now) {
        List<LineCurInfoVo> lineCurInfoVoList1 = sendCurNetStationInfo(now);
        lineCurInfoVoListMap.put(now, lineCurInfoVoList1);
        return lineCurInfoVoList1;
    }


    /**
     * @description: 发送线路信息
     * @author: renzhg
     * @date: 2025/2/7 14:55
     **/
    public void sendLineCurInfo(String now, LocalTime startTime, List<LineCurInfoVo> lineCurInfoVoList) {

        //5分钟以前的数据
        LocalTime localTime = LocalTime.parse(now);
        mqttSend.sendSimLineInfo(startTime, localTime, lineCurInfoVoList);

    }




    public NetCurInfoVo getNetCurInfo(String now, Map<String, TransferStation> transferStationMap, int inputNetTotal) {
        int retinputNetTotal = 0;
        NetCurInfoVo netCurInfoVo=new NetCurInfoVo();
        netCurInfoVo.setTimePt(now);

        if(now.equals("06:10:01")){
            System.out.println("start-----");
            Map<String, List<LineCurInfoVo>> lineCurInfoVoListMap =getLineCurInfoVoListMap();
            List<LineCurInfoVo> lineCurInfoVoList = lineCurInfoVoListMap.get(now);
            int lsInputNum=0;
            double lineFullLoadNum=0.0;
            int trainNum=0;
            for(LineCurInfoVo lineCurInfoVo : lineCurInfoVoList){
                lsInputNum=lsInputNum+lineCurInfoVo.getInputInstantLineNum();
                inputNetTotal=inputNetTotal+lsInputNum;
                lineFullLoadNum=lineFullLoadNum+lineCurInfoVo.getTrainFullLoadLine();
                trainNum=trainNum+lineCurInfoVo.getTrainOnLineNum();
                retinputNetTotal=retinputNetTotal+inputNetTotal;
            }
            int transferNum=0;
            for (Map.Entry< String, TransferStation> transferStationEntry:transferStationMap.entrySet()){
                TransferStation transferStation=transferStationEntry.getValue();
                transferNum=transferNum+transferStation.getTransferPersonsMap().size();
            }
            netCurInfoVo.setInputNetInstantNum(lsInputNum);
            netCurInfoVo.setInputNetTotalNum(inputNetTotal);
            netCurInfoVo.setFullLoadNet(lineFullLoadNum);
            netCurInfoVo.setNetTrainNum(trainNum);
            netCurInfoVo.setSceneCode(this.sceneCode);
            netCurInfoVo.setTransferNum(transferNum);
            netCurInfoVo.setTotalNetNum(inputNetTotal);


        }


        return netCurInfoVo;
    }



    public void  sendNetCurInfo(String now, LocalTime startTime,NetCurInfoVo netCurInfoVo) {

        LocalTime localTime = LocalTime.parse(now);
        mqttSend.sendNetCurInfo(startTime, localTime, netCurInfoVo);


    }



    public List<TrainCurInfoVo> getTrainCurInfoVoList(String now) {
        List<TrainCurInfoVo> trainCurInfoVos = trainCurInfoPublish(now);
        trainCurInfoVoListMap.put(now, trainCurInfoVos);
        return trainCurInfoVos;
    }
    /**
     * @description: 发送车辆信息
     * @author: renzhg
     * @date: 2025/2/7 14:58
     **/
    public void sendNetTrainInfo(String now, LocalTime startTime, List<TrainCurInfoVo> trainCurInfoVos) {

        LocalTime localTime = LocalTime.parse(now);
        mqttSend.sendSimtrainRunInfo(startTime, localTime, trainCurInfoVos);

    }

    /**
     * @description: 发送进度
     * @author: renzhg
     * @date: 2024/11/18 15:59
     **/
    public void caculatePercentage(String now, SceneParam sceneParam) {
        LocalTime endTime = sceneParam.getEndTime();
        LocalTime localTime = LocalTime.parse(now);
        Duration nowDuration = Duration.between(localTime, endTime);
        SceneControlStatus sceneControlStatus1 = UnitCache.sceneControlStatusMap.get(sceneCode);
        double lvalue = (double) (sceneControlStatus1.getStartTimeL() - nowDuration.getSeconds()) / sceneControlStatus1.getStartTimeL();
        String percentageString = String.format("%.2f%%", lvalue * 100);
        mqttSend.sendSimSchedule(percentageString, now);

    }

    /**
     * @description: 当前时间
     *
     * @author:  renzhg 
     * @date:  2025/2/7 15:01
     **/
    public void sendCurrentTime(String now, String sceneCode) {
        mqttSend.sendCurrentTime(now, sceneCode);

    }


    public List<TrainCurInfoVo> trainCurInfoPublish(String now) {
        List<TrainCurInfoVo> trainCurInfoVoList = new ArrayList<>();
        for (Map.Entry<String, LineRooter> lineRooterEntry : lineRooterMap.entrySet()) {
            List<String> finishedTrainList = lineRooterEntry.getValue().getTrainManager().getFinishedTrainList();
            TrainCurInfoVo trainCurInfoVo = lineRooterEntry.getValue().getLineInfoPublisher().trainCurInfoPublish(now);
            trainCurInfoVo.getDownLoadNetTrainIdMap().put(lineRooterEntry.getKey(), finishedTrainList);
            trainCurInfoVoList.add(trainCurInfoVo);
        }
        return trainCurInfoVoList;
    }


    //车辆信息在本地打印
    public void trainRecorderPublish(String now) {
        for (Map.Entry<String, LineRooter> lineRooterEntry : lineRooterMap.entrySet()) {
            lineRooterEntry.getValue().getLineInfoPublisher().trainRecorderPublish(now);
        }
    }


    public void recordPeople(String now) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm:ss");
        for (Map.Entry<String, LineRooter> lineRooterEntry : lineRooterMap.entrySet()) {
            List<BeforeFiveMinPeople> beforeFiveMinPeopleList = new ArrayList<>();
            for (Map.Entry<String, Station> stationEntry : lineRooterEntry.getValue().getStationInThisLineMap().entrySet()) {
                BeforeFiveMinPeople beforeFiveMinPeople = new BeforeFiveMinPeople();
                LocalTime startTime = UnitCache.sceneParamMap.get(this.sceneCode).getStartTime();
                LocalTime nowLocalTime = TimeUtil.convertStringToLocalTime(now);
                if (TimeUtil.compareLocalTimes(startTime, nowLocalTime) == 1 || TimeUtil.compareLocalTimes(nowLocalTime, startTime) == 0) {
                    //计算时间点
                    LocalTime newLocalTime = nowLocalTime.minusMinutes(5);
                    String fiveBeforeTimeString = newLocalTime.format(formatter);
                    // 5分钟数据前数据
                    Integer willInStationInstantNumFBF = stationEntry.getValue().getStationInstantInfo().getWillInStationInstantNumMap().get(fiveBeforeTimeString);
                    Integer willInStationTotalNumFBF = stationEntry.getValue().getStationInstantInfo().getWillInStationTotalNumMap().get(fiveBeforeTimeString);
                    Integer stationInstantInStationPersonNumFBF = stationEntry.getValue().getStationInstantInfo().getStationInstantInStationPersonNumMap().get(fiveBeforeTimeString);
                    Integer stationTotalInputPersonNumFBF = stationEntry.getValue().getStationInstantInfo().getStationTotalInputPersonNumMap().get(fiveBeforeTimeString);
                    Integer stationInstantOutPersonNumFBF = stationEntry.getValue().getStationInstantInfo().getStationInstantOutPersonNumMap().get(fiveBeforeTimeString);
                    Integer stationTotalOutPersonNumFBF = stationEntry.getValue().getStationInstantInfo().getStationTotalOutPersonNumMap().get(fiveBeforeTimeString);
                    beforeFiveMinPeople.setStationName(stationEntry.getValue().getName());
                    if (willInStationTotalNumFBF == null) {
                        beforeFiveMinPeople.setWillInStationTotalNum(0);
                    } else {
                        beforeFiveMinPeople.setWillInStationTotalNum(willInStationTotalNumFBF);
                    }


                    if (willInStationInstantNumFBF == null) {
                        beforeFiveMinPeople.setWillInTotalNum(0);
                    } else {
                        beforeFiveMinPeople.setWillInTotalNum(willInStationInstantNumFBF);
                    }

                    if (stationTotalInputPersonNumFBF == null) {
                        beforeFiveMinPeople.setInputTotalNum(0);
                    } else {
                        beforeFiveMinPeople.setInputTotalNum(stationTotalInputPersonNumFBF);
                    }


                    if (stationInstantInStationPersonNumFBF == null) {
                        beforeFiveMinPeople.setInputInstantNum(0);
                    } else {
                        beforeFiveMinPeople.setInputInstantNum(stationInstantInStationPersonNumFBF);
                    }

//                    beforeFiveMinPeople.setInputInstantNum(stationInstantInStationPersonNumFBF);


                    if (stationTotalOutPersonNumFBF == null) {
                        beforeFiveMinPeople.setOutputTotalNum(0);
                    } else {
                        beforeFiveMinPeople.setOutputTotalNum(stationTotalOutPersonNumFBF);
                    }
//                    beforeFiveMinPeople.setOutputTotalNum(stationTotalOutPersonNumFBF);
                    if (stationInstantOutPersonNumFBF == null) {
                        beforeFiveMinPeople.setOutputInstantNum(0);
                    } else {
                        beforeFiveMinPeople.setOutputInstantNum(stationInstantOutPersonNumFBF);
                    }
//                    beforeFiveMinPeople.setOutputInstantNum(stationInstantOutPersonNumFBF);

                }
                beforeFiveMinPeopleList.add(beforeFiveMinPeople);
            }
            beforeFiveMinPeopleMapEverypt.put(now, beforeFiveMinPeopleList);
        }


    }


    //发送线路单站信息的方法
    public List<LineCurInfoVo> sendCurNetStationInfo(String now) {
        List<LineCurInfoVo> lineCurInfoVoList = new ArrayList<>();
        for (Map.Entry<String, LineRooter> lineRooterEntry : lineRooterMap.entrySet()) {
            LineCurInfoVo lineCurInfoVo = lineRooterEntry.getValue().getLineInfoPublisher().linePublishInfo(now);
            lineCurInfoVoList.add(lineCurInfoVo);
        }
        return lineCurInfoVoList;


    }

}
